package com.yh.csx.demo.controller;

import com.alibaba.fastjson.TypeReference;
import com.yh.csx.bsf.redis.RedisProvider;
import com.yh.csx.bsf.redis.annotation.RedisCache;
import com.yh.csx.demo.model.User;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;


@Slf4j
@Api("缓存服务")
@RestController
@RequestMapping("/cache")
public class RedisController {

	private static final String LOCK_PRIFEX = "lock_test_";
	@Autowired
	private RedisProvider redisProvider;

	@GetMapping("/get")
	@ApiOperation("获取值")
	public String get(String key) {
		return redisProvider.get(key);
	}
	@ApiOperation("设置值")
	@GetMapping("/set")
	public void set(String key, String value, int timeout) {
		redisProvider.set(key, value, timeout);
	}

	@ApiOperation("分布式锁测试")
	@GetMapping("/lockTest")
	public void lockTest(String lockey, String time) {
		Random r = new Random();
		String key = LOCK_PRIFEX + lockey + r.nextInt(100);

			redisProvider.lock(key, 1, () -> {
				log.info("加锁成功：1 秒");
				try {
					log.info("程序运行" +  100 + "毫秒");
				
				
					Thread.sleep( 2000);
				}catch(Exception e) {
					log.error("错日志",e);
				} finally {
					log.info("解锁成功：" + key);
				}		
		});
		

	}

	@GetMapping("/call")
	@RedisCache(timeout = 60)
	public String call() {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
	}

	@GetMapping("/callVoid")
	@RedisCache(timeout = 60)
	public void callVoid() {
		System.out.println("call");
	}

	@GetMapping("/callList")
	@RedisCache(timeout = 60)
	public List<String> callList() {
		return Arrays.asList("1", "2", String.valueOf(Math.random()));
	}

	@GetMapping("/callArray")
	@RedisCache(timeout = 60)
	public String[] callArray(int length) {
		System.out.println("call");
		if (length != 10) {
			throw new IllegalArgumentException("length != 10");
		}
		return new String[length];
	}

	@GetMapping("/callComplex")
	@RedisCache(key = "'user-'+#userId", timeout = 60)
	public User callComplex(long userId) {
		return new User(userId, "hello: " + System.currentTimeMillis(),
				Arrays.asList(new User.Job(userId + "001", "haha")));
	}

	@GetMapping("/callComplexList")
	@RedisCache(key = "'list-user-'+#userId", timeout = 60)
	public List<User> callComplexList(long userId) {
		return Arrays.asList(new User(userId, "hello: " + System.currentTimeMillis(),
				Arrays.asList(new User.Job(userId + "001", "haha"))));
	}

	@GetMapping("/callComplexMap")
	@RedisCache(key = "'map-user-'+#userId", timeout = 60)
	public Map<Integer, User> callComplexMap(long userId) {
		Map<Integer, User> values = new HashMap<>();
		values.put((int) userId,
				new User(userId, "hello: " + userId, Arrays.asList(new User.Job(userId + "001", "haha"))));
		return values;
	}

	@GetMapping("/callback")
	public List<User> callback(long userId) {
		List<User> list = redisProvider.cache("user-" + userId, 60,
				() -> Arrays.asList(
						new User(userId, "hello: " + userId, Arrays.asList(new User.Job(userId + "001", "haha")))),
				new TypeReference<List<User>>() {
				}.getType());
		System.out.println(list);
		return list;
	}

	@GetMapping("/callbackMap")
	public Map<Integer, User> callbackMap(long userId) {
		Map<Integer, User> map = redisProvider.cache("user-" + userId, 60, () -> {
			Map<Integer, User> values = new HashMap<>();
			values.put((int) userId,
					new User(userId, "hello: " + userId, Arrays.asList(new User.Job(userId + "001", "haha"))));
			return values;
		}, new TypeReference<Map<Integer, User>>() {
		}.getType());
		return map;
	}

}
